---
title: Transaction-bracketed save
summary: Persist claim changes inside a single managed database transaction.
status: draft
owner: SAIF Documentation Generator
last_reviewed: 2026-08-21
library: SAIF.Application.Claim
reference_type: embedded
operation_id: OP-CLM-5
trigger: A UI save action on a derived manager calls Write().
---

# Transaction-bracketed save

This operation guarantees every claim save commits or rolls back as a single unit, regardless of how many business objects the derived manager writes inside `OnWrite()`.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-CLM-5 |
| **Trigger** | A UI save action on a derived manager calls `Write()` |
| **Inputs** | none (uses the current claim context and derived manager's pending changes) |
| **Outputs** | Success flag (`Boolean`) |
| **Primary components** | `ClaimAppManager.Write`, `ClaimAppManager.OnTransactionStart`, `ClaimAppManager.OnTransactionStop` |
| **Entry point** | `SAIF.Application.Claim/ClaimAppManager.vb` |

## Steps

1. `OnTransactionStart()` — if `Not DPI.TransactionPending`, call `DataLayer.DAL.BeginTransaction(DPI.PortalID)` ([BR-CLM-015](../business-rules.md#br-clm-015-single-transaction-per-save)).
2. `WriteResult = OnWrite()` — the derived manager persists its business objects (abstract in this library).
3. On exception: call `OnTransactionStop(False)` (rollback) and rethrow.
   - On the exception path the transaction is stopped twice (rollback in `Catch`, then again in `Finally`); the second call is a no-op because `TransactionPending` is then `False`.*
4. Finally: call `OnTransactionStop(WriteResult)` — if `DPI.TransactionPending`, call `DataLayer.DAL.EndTransaction(DPI.PortalID, inCommit)` ([BR-CLM-016](../business-rules.md#br-clm-016-commit-only-on-success)).
5. Return `WriteResult`.

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([Write called]) --> Begin{TransactionPending?}
	Begin -->|No| StartTx[BeginTransaction]
	Begin -->|Yes| SkipStart[Join existing transaction]
	StartTx --> DoWrite["OnWrite: derived manager<br>persists changes"]
	SkipStart --> DoWrite
	DoWrite --> Outcome{Exception or False result?}
	Outcome -->|Exception| Rollback1[OnTransactionStop False]
	Rollback1 --> Rethrow([Rethrow exception])
	Outcome -->|False, no exception| Stop2[OnTransactionStop False]
	Stop2 --> ReturnFalse([Return False])
	Outcome -->|True| Stop3["OnTransactionStop True:<br>EndTransaction commit"]
	Stop3 --> ReturnTrue([Return True])
```

## Failure and edge-case behavior

- A `False` result from `OnWrite()` without an exception causes `EndTransaction(..., False)` — a rollback ([BR-CLM-016](../business-rules.md#br-clm-016-commit-only-on-success)).
- Nested saves (a transaction already pending) join the outer transaction instead of starting a new one.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [Configuration](../configuration.md)

> **Note:** Statements marked with * were inferred from code structure, naming conventions, or
> contextual evidence where direct confirmation was not available in source artifacts. Statements
> marked with ** could not be confirmed; treat as unknown until verified.

## Sources
- `SAIF.Application.Claim/ClaimAppManager.vb`
